home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Report Writers / Crystal Repot 9.0 Full CD version / Setup.exe / SRC / HOARDDLL.ZIP / 3rdParty / hoard / libhoard-2.0.2 / processheap.h < prev    next >
Encoding:
C/C++ Source or Header  |  2002-06-18  |  7.5 KB  |  324 lines

  1. ///-*-C++-*-//////////////////////////////////////////////////////////////////
  2. //
  3. // Hoard: A Fast, Scalable, and Memory-Efficient Allocator
  4. //        for Shared-Memory Multiprocessors
  5. // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
  6. //
  7. // Copyright (c) 1998-2000, The University of Texas at Austin.
  8. //
  9. // This library is free software; you can redistribute it and/or modify
  10. // it under the terms of the GNU Library General Public License as
  11. // published by the Free Software Foundation, http://www.fsf.org.
  12. //
  13. // This library is distributed in the hope that it will be useful, but
  14. // WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19.  
  20.  
  21. //////////////////////////////////////////////////////////////////////////////
  22. //
  23. // Note: This file was modified by Crystal Decisions in June 2002.
  24. //
  25. //////////////////////////////////////////////////////////////////////////////
  26.  
  27.  
  28. /*
  29.   processheap.h
  30.   ------------------------------------------------------------------------
  31.   We use one processHeap for the whole program.
  32.   ------------------------------------------------------------------------
  33.   @(#) $Id: processheap.h,v 1.68 2000/03/22 07:50:30 emery Exp $
  34.   ------------------------------------------------------------------------
  35.   Emery Berger                    | <http://www.cs.utexas.edu/users/emery>
  36.   Department of Computer Sciences |             <http://www.cs.utexas.edu>
  37.   University of Texas at Austin   |                <http://www.utexas.edu>
  38.   ========================================================================
  39. */
  40.  
  41. #ifndef _PROCESSHEAP_H_
  42. #define _PROCESSHEAP_H_
  43.  
  44. #include "config.h"
  45.  
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48.  
  49. #include "arch-specific.h"
  50. #include "heap.h"
  51. #if USE_PRIVATE_HEAPS
  52. #include "privateheap.h"
  53. #define HEAPTYPE privateHeap
  54. #else
  55. #define HEAPTYPE threadHeap
  56. #include "threadheap.h"
  57. #endif
  58.  
  59. #if HEAP_LOG
  60. #include "memstat.h"
  61. #include "log.h"
  62. #endif
  63.  
  64. class processHeap : public hoardHeap {
  65.  
  66. public:
  67.  
  68.   // Always grab at least this many superblocks' worth of memory which
  69.   // we parcel out.
  70.   enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
  71.  
  72.   processHeap (void);
  73.  
  74.   ~processHeap (void) {
  75. #if HEAP_STATS
  76.     stats();
  77. #endif
  78.   }
  79.  
  80.   // Memory deallocation routines.
  81.   void free (void * ptr);
  82.  
  83.   // Print out statistics information.
  84.   void stats (void);
  85.  
  86.   // Get a thread heap index.
  87.   inline int getHeapIndex (void);
  88.  
  89.   // Get the thread heap with index i.
  90.   inline HEAPTYPE& getHeap (int i);
  91.  
  92.   // Extract a superblock.
  93.   inline superblock * acquire (const int c,
  94.                    hoardHeap * dest);
  95.  
  96.   // Get space for a superblock.
  97. #ifndef CRYSTAL_HOARD
  98.   inline char * getSuperblockBuffer (void);
  99. #else
  100.   inline char * getSuperblockBuffer (const int superblockClass);
  101. #endif
  102.  
  103.   // Insert a superblock.
  104. #ifdef CRYSTAL_HOARD
  105.   inline bool release (superblock * sb);
  106. #else
  107.   inline void release (superblock * sb);
  108. #endif
  109.  
  110. #if HEAP_LOG
  111.   // Get the log for index i.
  112.   inline Log<MemoryRequest>& getLog (int i);
  113. #endif
  114.  
  115. #if HEAP_FRAG_STATS
  116.   // Declare that we have allocated an object.
  117.   void setAllocated (int requestedSize,
  118.              int actualSize);
  119.  
  120.   // Declare that we have deallocated an object.
  121.   void setDeallocated (int requestedSize,
  122.                int actualSize);
  123.  
  124.   // Return the number of wasted bytes at the high-water mark
  125.   // (maxAllocated - maxRequested)
  126.   inline int getFragmentation (void);
  127.  
  128.   int getMaxAllocated (void) {
  129.     return _maxAllocated;
  130.   }
  131.  
  132.   int getInUseAtMaxAllocated (void) {
  133.     return _inUseAtMaxAllocated;
  134.   }
  135.  
  136.   int getMaxRequested (void) {
  137.     return _maxRequested;
  138.   }
  139.   
  140. #endif
  141.  
  142. private:
  143.  
  144.   // Hide the lock & unlock methods.
  145.  
  146.   void lock (void) {
  147.     hoardHeap::lock();
  148.   }
  149.  
  150.   void unlock (void) {
  151.     hoardHeap::unlock();
  152.   }
  153.  
  154.   // Prevent copying and assignment.
  155.   processHeap (const processHeap&);
  156.   const processHeap& operator= (const processHeap&);
  157.  
  158.   // The per-thread heaps.
  159.   HEAPTYPE theap[MAX_HEAPS];
  160.  
  161. #if HEAP_FRAG_STATS
  162.   // Statistics required to compute fragmentation.  We cannot
  163.   // unintrusively keep track of these on a multiprocessor, because
  164.   // this would become a bottleneck.
  165.  
  166.   int _currentAllocated;
  167.   int _currentRequested;
  168.   int _maxAllocated;
  169.   int _maxRequested;
  170.   int _inUseAtMaxAllocated;
  171.   int _fragmentation;
  172.  
  173.   // A lock to protect these statistics.
  174.   hoardLockType _statsLock;
  175. #endif
  176.  
  177. #if HEAP_LOG
  178.   Log<MemoryRequest> _log[MAX_HEAPS + 1];
  179. #endif
  180.  
  181.   // A lock for the superblock buffer.
  182.   hoardLockType _bufferLock;
  183.  
  184.   char *     _buffer;
  185.   int         _bufferCount;
  186. };
  187.  
  188.  
  189. HEAPTYPE& processHeap::getHeap (int i)
  190. {
  191.   assert (i >= 0);
  192.   assert (i < MAX_HEAPS);
  193.   return theap[i];
  194. }
  195.  
  196.  
  197. #if HEAP_LOG
  198. Log<MemoryRequest>& processHeap::getLog (int i)
  199. {
  200.   assert (i >= 0);
  201.   assert (i < MAX_HEAPS + 1);
  202.   return _log[i];
  203. }
  204. #endif
  205.  
  206.  
  207. // Return ceil(log_2(num)).
  208. // num must be positive.
  209. static int lg (int num)
  210. {
  211.   assert (num > 0);
  212.   int power = 0;
  213.   int n = 1;
  214.   // Invariant: 2^power == n.
  215.   while (n < num) {
  216.     n <<= 1;
  217.     power++;
  218.   }
  219.   return power;
  220. }
  221.  
  222.  
  223. // Hash out the thread id to a heap and return an index to that heap.
  224. int processHeap::getHeapIndex (void) {
  225.   // Here we use the number of processors as the maximum number of heaps.
  226.   // In fact, for efficiency, we just round up to the highest power of two,
  227.   // times two.
  228.   static const int numProcessors = hoardGetNumProcessors();
  229.   static const int numProcessorsMask = (1 << (lg(numProcessors) + 1)) - 1;
  230.  
  231.   int tid = hoardGetThreadID() & numProcessorsMask;
  232.   assert (tid < MAX_HEAPS);
  233.  
  234.   return tid;
  235. }
  236.  
  237.  
  238. superblock * processHeap::acquire (const int sizeclass,
  239.                    hoardHeap * dest)
  240. {
  241.   lock ();
  242.  
  243.   // Remove the superblock with the most free space.
  244.   superblock * maxSb = removeMaxSuperblock (sizeclass);
  245.   if (maxSb) {
  246.     maxSb->setOwner (dest);
  247.   }
  248.  
  249.   unlock ();
  250.  
  251.   return maxSb;
  252. }
  253.  
  254.  
  255. #ifndef CRYSTAL_HOARD
  256. inline char * processHeap::getSuperblockBuffer (void)
  257. {
  258.   char * buf;
  259.   hoardLock (_bufferLock);
  260.   if (_bufferCount == 0) {
  261.     _buffer = (char *) hoardSbrk (SUPERBLOCK_SIZE * REFILL_NUMBER_OF_SUPERBLOCKS);
  262.     _bufferCount = REFILL_NUMBER_OF_SUPERBLOCKS;
  263.   }
  264.   buf = _buffer;
  265.   _buffer += SUPERBLOCK_SIZE;
  266.   _bufferCount--;
  267.   hoardUnlock (_bufferLock);
  268.   return buf;
  269. }
  270. #else
  271. inline char * processHeap::getSuperblockBuffer ( const int superblockClass )
  272. {
  273.   char * buf;
  274.  
  275.   assert(superblockClass >= 0);
  276.   assert(superblockClass < hoardHeap::SUPERBLOCK_CLASSES);
  277.  
  278.   size_t superblockSize = superblockSizeFromClass(superblockClass);
  279.   buf = (char *) hoardSbrk( superblockSize );
  280.  
  281.   return buf;
  282. }
  283. #endif
  284.  
  285.  
  286. // Put a superblock back into our list of superblocks.
  287. #ifdef CRYSTAL_HOARD
  288. bool processHeap::release (superblock * sb)
  289. #else
  290. void processHeap::release (superblock * sb)
  291. #endif
  292. {
  293.   assert (EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
  294.  
  295.   lock();
  296.  
  297. #ifdef CRYSTAL_HOARD
  298.   assert (sb != NULL);
  299.   assert (sb->getPrev() == NULL);
  300.   assert (sb->getNext() == NULL);
  301.   if ((sb->getFullness() == 0) &&
  302.       (sb->getNumBlocks() == sb->getNumAvailable()))
  303.   {
  304.       if (unsbrkIfLimit(this,sb)) {
  305.         unlock();
  306.         return true;
  307.       }
  308.   }
  309. #endif
  310.  
  311.   // Insert the superblock.
  312.   insertSuperblock (sb->getBlockSizeClass(), sb, this);
  313.  
  314.   unlock();
  315.  
  316. #ifdef CRYSTAL_HOARD
  317.   return false;
  318. #endif
  319. }
  320.  
  321.  
  322. #endif // _PROCESSHEAP_H_
  323.  
  324.